module ysyx_22040213_nextpc(
	input clk,
	input rst,

	input exe_reg_w_en,
	input IF_allow_in,

	input [63:0] src1,
	input [63:0] ext_imm,
	input [63:0] pc_add_four,
	input [63:0] mtvec,
	input [63:0] mepc,
	input IF_valid,
	input [4:0] nextpc_en,
//	input jumpb_en,
	input [63:0] pc,
	output [63:0]dnpc,
	output reg br_bus_valid,
	
//------------buffer handshake-------------------//
//	input IF_allow_in,
	input inst_addr_ok,
	input pc_stall,
	input valid_in,
	input clint_trap_go,

	output o_clint_trap_go,
	output pc_ready_go,
	output to_fs_valid
		
);
//-----------------------pre-if-----------------// 
	assign pc_ready_go = !pc_stall && valid_in && inst_addr_ok;
	wire [63:0] dnpc_i;
	wire i_jump_en = |nextpc_en;
		
	assign to_fs_valid = pc_ready_go;

	reg [63:0] br_bus_reg;
	reg [4:0] nextpc_en_reg;
	reg bd_done;
	reg clint_trap_reg;

	MuxKey #(6, 5, 64) i0 (dnpc_i, nextpc_en, {
		5'b00000, pc+4,
		5'b00001, (ext_imm + src1) & ~64'b1,
		5'b00010, pc_add_four + ext_imm - 4,
		5'b00100, pc_add_four + ext_imm - 4,
		5'b01000, mtvec,
		5'b10000, mepc
		});
	assign dnpc = (~IF_valid && ((|nextpc_en_reg & br_bus_valid) || (|nextpc_en))) && ~bd_done? pc+4 : ((|nextpc_en_reg & br_bus_valid) ) ? br_bus_reg : dnpc_i;
	
	assign o_clint_trap_go = (~IF_valid && ((|nextpc_en_reg & br_bus_valid) || (|nextpc_en))) && ~bd_done? 1'b0 : ((|nextpc_en_reg & br_bus_valid) ) ? clint_trap_reg : clint_trap_go;


	always @(posedge clk)begin
	  if(rst)begin
	    br_bus_reg <= 64'b0;
	    br_bus_valid <= 1'b0;
	    nextpc_en_reg <= 5'b0;
          end else if( ~((~IF_valid && ((|nextpc_en_reg & br_bus_valid) || (|nextpc_en))) && ~bd_done) && ((|nextpc_en_reg & br_bus_valid) || (|nextpc_en)) && pc_ready_go && IF_allow_in) begin
	    br_bus_valid <= 1'b0;
	    br_bus_reg <= dnpc_i;
	    nextpc_en_reg <= nextpc_en;
	    clint_trap_reg <= clint_trap_go;
         end else if(exe_reg_w_en && i_jump_en && !pc_stall)begin
	    br_bus_reg <= dnpc_i;
	    nextpc_en_reg <= nextpc_en;
	    br_bus_valid <= 1'b1;
	    bd_done <= 1'b0;
	    clint_trap_reg <= clint_trap_go;
    	  end else if ((|nextpc_en_reg & br_bus_valid) && IF_valid)begin
	    bd_done <= 1'b1;
	  end else if(~br_bus_valid)begin
	    bd_done <= 1'b0;
    	  end else begin
	  end
	end
endmodule
